﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Windows.Forms;
using Lidgren.Network;
using Model.LiveControl;
using Network;
using Network.Messages.LiveControl;

namespace Providers.LiveControl.Server.FormsControl
{
    public class FormsControl : IHeartbeat, ICheckAllowOperationable
    {
        private readonly Dictionary<string, FormItem> _formItems = new Dictionary<string, FormItem>();

        private DateTime _deadTime = DateTime.Now;

        private void RefreshDeadTime()
        {
            _deadTime = DateTime.Now.AddSeconds(30);
        }

        private bool CheckTimeOut()
        {
            return DateTime.Now > _deadTime;
        }

        public FormsControl()
        {
            FormeNameList = new List<string>
            {
                "1-BLOOMBERG",
                "2-BLOOMBERG",
                "3-BLOOMBERG",
                "4-BLOOMBERG"
            };
        }

        private List<string> FormeNameList { get; }

        public FormItemModel[] Models
        {
            get
            {
                FormItemModel[] models = new FormItemModel[_formItems.Values.Count];

                int i = 0;
                foreach (var value in _formItems.Values)
                {
                    models[i] = value.GetModel();
                    i++;
                }
                return models;
            }
        }

        private NetConnection _currentConnection;
        private NetConnection _preSetConnection;
        public void PreSetConnection(NetConnection connection)
        {
            _preSetConnection = connection;
        }

        public void AcceptPreSetConnection()
        {
            SetCurrentControl(_preSetConnection);
        }

        public NetConnection RefuseConnection()
        {
            var temp = _preSetConnection;
            _preSetConnection = null;
            return temp;
        }

        public bool CheckAllowOperation(NetConnection connection)
        {
            // 如果之前的连接失效，将当前连接设置为可控连接
            if (_currentConnection == null || _currentConnection.Status != NetConnectionStatus.Connected || (CheckTimeOut()&& !Equals(_currentConnection.RemoteEndPoint, connection.RemoteEndPoint)))
            {
                SetCurrentControl(connection);
                return true;
            }

            // 如果是可控连接，更新失效时间
            if (Equals(_currentConnection.RemoteEndPoint, connection.RemoteEndPoint))
            {
                RefreshDeadTime();
                return true;
            }
            return false;
        }

        public void Heartbeat(float now, uint frameCounter)
        {
            UpdateFormList(FormeNameList);
        }

        public event EventHandler<FormItem> FormClosedEvent;
        public event EventHandler<FormItem> FormMinisizedEvent;
        public event EventHandler<FormItem> FormStatusUpdate;

        public event EventHandler<FormItemChangedArgs> CurrentFormChanged;

        public void SetCurrentControl(NetConnection connection)
        {
            CurrentFormChanged?.Invoke(this, new FormItemChangedArgs
            {
                NewConnection = connection,
                OldConnection = _currentConnection
            });
            _currentConnection = connection;
            RefreshDeadTime();
        }

        private void UpdateFormList(List<string> exeFormNameList)
        {
            foreach (var exeFormName in exeFormNameList)
            {
                FormItem itemTemp;
                // 如果字典有就获取，没有就创建一个
                if (!_formItems.TryGetValue(exeFormName, out itemTemp))
                {
                    itemTemp = new FormItem { ExeFormName = exeFormName };
                    _formItems.Add(exeFormName, itemTemp);
                }

                // 如果对象的ptr == zero 获取一个
                if (itemTemp.Ptr == IntPtr.Zero || !WindowApi.IsWindow(itemTemp.Ptr))
                {
                    var ptr = WindowApi.FindWindow(null, exeFormName);

                    if (ptr != IntPtr.Zero)
                    {
                        itemTemp.Ptr = ptr;
                    }
                    else
                    {
                        // 事件 通知
                        if (itemTemp.Ptr != IntPtr.Zero)
                        {
                            FormClosedEvent?.Invoke(this, itemTemp);
                        }
                        itemTemp.Ptr = IntPtr.Zero;
                    }
                }

                // 获取窗体所在屏幕
                if (itemTemp.Ptr != IntPtr.Zero)
                {
                    var screen = Screen.FromHandle(itemTemp.Ptr);
                    var deviceName = screen.DeviceName;

                    itemTemp.DeviceName = deviceName;

                    bool mini = WindowApi.IsIconic(itemTemp.Ptr);

                    // 如果窗口处于最小化状态，而且之前是最大化的时候，也就是刚被最小化时触发事件
                    if (mini && !itemTemp.FlagMinisized)
                        FormMinisizedEvent?.Invoke(this, itemTemp);

                    // 同步窗口最小化状态
                    itemTemp.FlagMinisized = mini;

                }
                if (itemTemp.Changed)
                {
                    FormStatusUpdate?.Invoke(this, itemTemp);
                    itemTemp.Changed = false;
                }
            }
        }

        public FormItem ConnectForm(FormItemModel model, NetConnection connection)
        {
            _formItems[model.ExeFormName].AddConnection(connection);
            return _formItems[model.ExeFormName];
        }

      
        public NetConnection GetCurrentConnection()
        {
            return _currentConnection;
        }
    }
}